
#include "packet_public.h"
#include <string.h>

message_t message;     /* current message structure */
mm_t MM;               /* memory manager will allocate memory for packets */
int pkt_cnt = 0;       /* how many packets have arrived for current message */
int pkt_total = 1;     /* how many packets to be received for the message */
int NumMessages = 5;   /* number of messages we will receive */
int cnt_msg=1;         /*current message being received*/

packet_t get_packet (size) {
	packet_t pkt;
	static int which;
	
	pkt.how_many = size;
	which=rand()%pkt.how_many; //the order in which packets will be sent is random.
	pkt.which = which;
	if (which == 0)
		strcpy (pkt.data, "aaaaaaa\0");
	else if (which == 1)
		strcpy (pkt.data, "bbbbbbb\0");
	else if(which == 2)
		strcpy (pkt.data, "ccccccc\0");
	else if(which == 3)
		strcpy (pkt.data, "ddddddd\0");
	else
		strcpy (pkt.data, "eeeeeee\0");
	return pkt;
}


void packet_handler(int sig)
{
	packet_t pkt;
	//  fprintf (stderr, "IN PACKET HANDLER, sig=%d\n", sig);
	static void *mess; //To be available through each call of this handler
	static int Pos;  //Again will not be intterupted, and thus this carries the pos of the address of mess
	static int sizeData; //Carries the size of the data to be used 
	
	pkt = get_packet(cnt_msg); // the messages are of variable length. So, the 1st message consists of 1 packet, the 2nd message consists of 2 packets and so on..
	pkt_total = pkt.how_many;
	
	if(pkt.which == pkt_cnt)
	{
		if(pkt_cnt==0)
		{ // when the 1st packet arrives, the size of the whole message is allocated.
	
			sizeData = (int) sizeof(data_t);
			mess = (void*) mm_get(&MM,sizeData * pkt_total);
			Pos = 0; //Used when printing/saving the address index of mess without changing the actual address of the message
		
		} 

  		memcpy(mess + Pos * sizeData, pkt.data, sizeof(data_t)); //Uses Sizeof Data_t assuming that whatever information you choose, it will stored uisng data_t, some assumptions had to be made
		message.num_packets++;
		Pos++;
		pkt_cnt++;

		/* insert your code here ... stick packet in memory, make sure to handle duplicates appropriately */
		//No duplicates will be allowed through, thus they won't be allocated and then there will be no need to release them
	}
	
	if(message.num_packets == pkt_total) //Means all messages have arrived, now to print them 
	{
		/*Print the packets in the correct order.*/
		
		int i;
		for(i = 0; i < message.num_packets;i++)
		{
			if(i == 0)
			{
				printf("Message %d Recieved: \n", cnt_msg);
			}
			printf("%s \n", mess + i * sizeData);
		}
	
		/*Deallocate message*/
		mm_put(&MM,mess);
	}
}


int main (int argc, char **argv)
{          
	/* set up alarm handler -- mask all signals within it */
	struct sigaction act;

	act.sa_handler = packet_handler;
	act.sa_flags = 0;
	
	if((sigemptyset(&act.sa_mask) == -1) || (sigfillset(&act.sa_mask) == -1) || (sigdelset(&act.sa_mask,SIGALRM) == -1))
	{
		perror("Failed to Iniitalize Signal Set");
	}
	
	if(sigprocmask(SIG_SETMASK, &act.sa_mask, NULL) == -1)
	{
		perror("Failed to block all signals");
	}
	
	sigaction(SIGALRM,&act,NULL);
	
	/* turn on alarm timer ... use  INTERVAL and INTERVAL_USEC for sec and usec values */
	struct itimerval time; 
	time.it_interval.tv_sec = INTERVAL;   //Time reloaded into the timer
	time.it_interval.tv_usec = INTERVAL_USEC;
	time.it_value.tv_sec = INTERVAL;   //Time until next timer goes off
	time.it_value.tv_usec = INTERVAL_USEC;
	if(setitimer(ITIMER_REAL, &time, NULL) == -1) //Decrements in real time, and then generates a SIGALRM
	{
		perror("Problem Setting Interval Timer");
	}
	
	message.num_packets = 0;
	mm_init (&MM, 200);	
	
	int j;
	for (j=1; j<=NumMessages; j++) {
		while (pkt_cnt < pkt_total) 
			pause();

		// reset these for next message 
		pkt_total = 1;
		pkt_cnt = 0;
		message.num_packets = 0;
		cnt_msg++;
		// anything else?

	}
	/* Deallocate memory manager */
	mm_release(&MM);
	return 0;
}
